package com.franklin.ideaplugin.easytesting.controllerclient.request;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.franklin.ideaplugin.easytesting.common.utils.JsonUtils;
import com.franklin.ideaplugin.easytesting.common.utils.ReflectionUtils;
import com.franklin.ideaplugin.easytesting.controllerclient.beans.RequestData;
import com.franklin.ideaplugin.easytesting.controllerclient.utils.ControllerUtil;
import lombok.AllArgsConstructor;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 参数在请求中的位置
 *
 * @author Ye Junhui
 * @since 2023/6/28
 */
@AllArgsConstructor
public enum RequestPosition implements IRequestFiller{

    HEADER(new IRequestFiller() {
        @Override
        public boolean fill(RequestData requestData, String parameterName, Class<?> parameterType, Object arg) {
            if (Objects.isNull(arg)){
                return false;
            }
            requestData.getHttpHeaders().add(parameterName,String.valueOf(arg));
            return true;
        }
    }),
    FORM_DATA(new IRequestFiller() {
        @Override
        public boolean fill(RequestData requestData, String parameterName, Class<?> parameterType, Object arg) {
            if (Objects.isNull(arg)){
                return false;
            }
            MultiValueMap<String, String> formData = requestData.getFormData();
            if (ControllerUtil.isFileType(parameterType)){
                //文件
                String filePath = String.valueOf(arg);
                requestData.getFileData().add(parameterName,filePath);
            }else if (!ReflectionUtils.isBasicType(parameterType)){
                LinkedHashMap linkedHashMap = JsonUtils.parseObject(arg.toString(), LinkedHashMap.class);
                if (CollectionUtil.isNotEmpty(linkedHashMap)){
                    linkedHashMap.forEach((k,v) -> formData.add(String.valueOf(k),String.valueOf(v)));
                }else {
                    List<?> list = JsonUtils.parseObject(arg.toString(), List.class);
                    if (CollectionUtil.isNotEmpty(list)){
                        list.stream()
                                .map(String::valueOf)
                                .forEach(s -> formData.add(parameterName,s));
                    }
                }
            } else {
                formData.add(parameterName,String.valueOf(arg));
            }
            return true;
        }
    }),
    PATH(new IRequestFiller() {
        @Override
        public boolean fill(RequestData requestData, String parameterName, Class<?> parameterType, Object arg) {
            if (Objects.isNull(arg)){
                return false;
            }
            requestData.getPathParams().put(parameterName,String.valueOf(arg));
            return true;
        }
    }),
    BODY(new IRequestFiller() {
        @Override
        public boolean fill(RequestData requestData, String parameterName, Class<?> parameterType, Object arg) {
            if (Objects.isNull(arg)){
                return false;
            }
            requestData.setRequestBody(arg);
            return true;
        }
    }),
    IGNORE(new IRequestFiller() {
        @Override
        public boolean fill(RequestData requestData, String parameterName, Class<?> parameterType, Object arg) {
            return true;
        }
    }),
    ;

    private final IRequestFiller delegate;

    @Override
    public boolean fill(RequestData requestData, String parameterName, Class<?> parameterType, Object arg) {
        return this.delegate.fill(requestData, parameterName, parameterType, arg);
    }
}
